import permission from '@/common/permission';
import md5Libs from '@/uview-ui/libs/function/md5';
import config from '@/common/config';

const parseurl = (data) => {
  let str = '?';
  // eslint-disable-next-line guard-for-in,no-restricted-syntax
  for (const item in data) {
    str += `${item}=${data[item]}&`;
  }
  return str.slice(0, -1);
};

const isObject = (obj) => Object.prototype.toString.call(obj) === '[object Object]';

// eslint-disable-next-line func-names
const debounce = (fn, delay = 200) =>
  function (...args) {
    const th = this;
    if (fn.id) clearTimeout(fn.id);
    // eslint-disable-next-line no-param-reassign
    fn.id = setTimeout(() => {
      fn.apply(th, args);
    }, delay);
  };

const throttle = (fn, delay = 200) => {
  let lastTime = 0;
  // eslint-disable-next-line func-names
  return function (...args) {
    const th = this;
    const currentTime = Date.now();
    if (currentTime - lastTime > delay) {
      fn.apply(th, args);
      lastTime = currentTime;
    }
  };
};

const dateFormat = (timestamp, fmt) => {
  // eslint-disable-next-line no-param-reassign
  if (typeof timestamp == 'string') timestamp = timestamp.replace(/-/g, '/');
  const date = new Date(timestamp);
  const o = {
    'M+': date.getMonth() + 1, // 月份
    'D+': date.getDate(), // 日
    'h+': date.getHours(), // 小时
    'm+': date.getMinutes(), // 分
    's+': date.getSeconds(), // 秒
    'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
    S: date.getMilliseconds(), // 毫秒
    w: '星期'+'日一二三四五六'.charAt(date.getDay()),
  };
  if (/(Y+)/.test(fmt)) {
    // eslint-disable-next-line no-param-reassign
    fmt = fmt.replace(RegExp.$1, `${date.getFullYear()}`.substr(4 - RegExp.$1.length));
  }
  // eslint-disable-next-line no-restricted-syntax
  for (const k in o) {
    if (new RegExp(`(${k})`).test(fmt)) {
      // eslint-disable-next-line no-param-reassign
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length == 1 ? o[k] : `00${o[k]}`.substr(`${o[k]}`.length)
      );
    }
  }
  return fmt;
};

const filterEmpty = (data) =>
  Object.keys(data)
    .filter((key) => data[key] !== null && data[key] !== undefined && data[key] !== '')
    .reduce((acc, key) => ({ ...acc, [key]: data[key] }), {});

/**
 * @description uni.chooseImage封装
 * @param options uni.chooseImage一样的参数
 */
const uniChooseImage = (options) => {
  // #ifdef APP-PLUS
  if (!permission.isIOS) {
    const start = Date.now();
    permission.requestAndroid('android.permission.READ_EXTERNAL_STORAGE').then((res) => {
      if (res === -1) {
        if (Date.now() - start <= 500) {
          uni.showModal({
            title: '无法访问相册中的照片',
            content: '请点击前往设置-权限管理-读写存储中开启存储权限',
            confirmText: '前往设置',
            cancelText: '取消',
            success: (res) => {
              if (res.confirm) {
                permission.gotoAppSetting();
              }
            },
          });
        }
        return;
      }

      if (res === 1) {
        uni.chooseImage(options);
      }
    });
    return;
  }
  // #endif
  // #ifdef MP-WEIXIN
  uni.getSetting({
    success(res) {
      if (!res.authSetting['scope.writePhotosAlbum']) {
        uni.authorize({
          scope: 'scope.writePhotosAlbum',
          success() {
            // 用户已授权，可以继续你的操作
            uni.chooseImage(options);
          },
          fail() {
            // 用户拒绝授权，可引导用户开启权限
            uni.showModal({
              title: '提示',
              content: '此功能需要保存相册的权限，请检查设置',
              // ... 引导用户到设置页面等操作
              success(res) {
                if (res.confirm) {
                  uni.openSetting(); // 打开小程序设置页面，可以让用户开启需要的权限
                }
              }
            });
          }
        });
      } else {
        // 已经授权，可以直接调用uni.chooseImage
        uni.chooseImage(options);
      }
    }
  });
  return;
  // #endif
  uni.chooseImage(options);
};

/**
 * @description uni.getClipboardData封装
 * @param options uni.getClipboardData一样的参数
 */
const uniGetClipboardData = (options) => {
  wx.getClipboardData(options);
  return;
  // #ifdef MP-WEIXIN
  // uni.getSetting({
  //   success(res) {
  //     if (!res.authSetting['scope.clipboard']) {
  //       uni.authorize({
  //         scope: 'scope.clipboard',
  //         success() {
  //           // 用户已授权，可以继续你的操作
  //           uni.getClipboardData(options);
  //         },
  //         fail() {
  //           // 用户拒绝授权，可引导用户开启权限
  //           uni.showModal({
  //             title: '提示',
  //             content: '此功能需要读取剪贴板，请在设置中允许',
  //             // ... 引导用户到设置页面等操作
  //             success(res) {
  //               if (res.confirm) {
  //                 uni.openSetting(); // 打开小程序设置页面，可以让用户开启需要的权限
  //               }
  //             }
  //           });
  //         }
  //       });
  //     } else {
  //       // 已经授权，可以直接调用uni.getClipboardData
  //       uni.getClipboardData(options);
  //     }
  //   }
  // });
  // return;
  // #endif
  uni.getClipboardData(options);
};
/**
 * @description uni.setClipboardData封装
 * @param options uni.setClipboardData一样的参数
 */
const uniSetClipboardData = (options) => {
  wx.setClipboardData(options);
  return;
  // #ifdef MP-WEIXIN
  // uni.getSetting({
  //   success(res) {
  //     if (!res.authSetting['scope.clipboard']) {
  //       uni.authorize({
  //         scope: 'scope.clipboard',
  //         success() {
  //           // 用户已授权，可以继续你的操作
  //           uni.setClipboardData(options);
  //         },
  //         fail() {
  //           // 用户拒绝授权，可引导用户开启权限
  //           uni.showModal({
  //             title: '提示',
  //             content: '此功能需要读取剪贴板，请在设置中允许',
  //             // ... 引导用户到设置页面等操作
  //             success(res) {
  //               if (res.confirm) {
  //                 uni.openSetting(); // 打开小程序设置页面，可以让用户开启需要的权限
  //               }
  //             }
  //           });
  //         }
  //       });
  //     } else {
  //       // 已经授权，可以直接调用uni.setClipboardData
  //       uni.setClipboardData(options);
  //     }
  //   }
  // });
  // return;
  // #endif
  uni.setClipboardData(options);
};

/**
 * @description 随机生成uuid
 * @return string
 */
const uuid = () => Number(new Date().getTime()) + Math.random().toString(36).substr(2, 15);

/**
 * @description 获取支付有效期
 * @param type 订单类型
 * @param systemInfo 系统配置
 * @return number
 */
const getTimeLimit = (type, systemInfo) => {
  if (type) type = Number(type);
  let timeLimit = 0;
  if ([0, 3, 8].includes(type)) {
    timeLimit = systemInfo.resaleTimeLimit;
  } else if (type == 1) {
    timeLimit = systemInfo.wholesaleTimeLimit;
  } else if (type == 4) {
    timeLimit = systemInfo.integralMallTimeLimit;
  } else if (
    /* eslint-disable */
    [
      2, 5, 9, 10, 12, 13, 14, 15, 500, 501, 502, 600, 20, 21, 2001, 2002, 888, 887, 200, 201,
    ].includes(type)
    /* eslint-disable */
  ) {
    timeLimit = systemInfo.generalTimeLimit;
  }
  return timeLimit;
};

class CountDown {
  /**
   * @description 倒计类
   * @param initCount 倒计时秒数
   * @param callback 每一秒回调
   */
  constructor(initCount = 60, callback = () => {}) {
    this._initCount = initCount;
    this._countDownCallback = callback;
  }

  _timer = null;

  run() {
    const that = this;
    return new Promise((resolve) => {
      let count = that._initCount;
      if (count <= 0) return resolve();
      const start = Date.now();
      const seed = 1000;
      let offset = 0;
      let nextTime = seed - offset;
      that._timer = setTimeout(countDown, nextTime);

      function countDown() {
        that._countDownCallback(--count);
        if (count === 0) {
          that.clear();
          that._countDownCallback(that._initCount);
          return resolve();
        }
        offset = Date.now() - (start + (that._initCount - count) * seed);
        nextTime = Math.max(seed - offset, 0);
        that._timer = setTimeout(countDown, nextTime);
      }
    });
  }

  clear() {
    if (this._timer) {
      clearTimeout(this._timer);
      this._timer = null;
    }
  }
}

/**
 * @description 密码加密通用方法
 * @param psd 密码
 * @param iv 偏移量
 * @return string
 */
const encryptPassword = (psd, iv = 'SKService') => {
  return md5Libs.md5(`${iv}${psd}`);
};

const scriptLoadedMap = new Map();
const loadScript = (url) => {
  if (scriptLoadedMap.has(url)) return Promise.resolve();
  return new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.src = url;
    const body = document.querySelector('body');
    body.appendChild(script);
    script.onload = function () {
      scriptLoadedMap.set(url, true);
      resolve();
    };
    script.onerror = function (err) {
      reject(new Error(err));
    };
  });
};

const compareVersion = (newVersion, curVersion) => {
  const newVersionArr = newVersion.toString().split('.');
  const curVersionArr = curVersion.toString().split('.');

  if (newVersionArr.length == curVersionArr.length) {
    for (let i = 0; i < newVersionArr.length; i++) {
      if (Number(newVersionArr[i]) > Number(curVersionArr[i])) {
        return true;
      } else if (Number(newVersionArr[i]) < Number(curVersionArr[i])) {
        return false;
      } else if (Number(newVersionArr[i]) == Number(curVersionArr[i])) {
        // return false
      }
    }
  } else {
    if (newVersionArr.length > curVersionArr.length) {
      for (let i = 0; i < curVersionArr.length; i++) {
        if (Number(newVersionArr[i]) > Number(curVersionArr[i])) {
          return true;
        } else if (Number(newVersionArr[i]) < Number(curVersionArr[i])) {
          return false;
        } else if (Number(newVersionArr[i]) == Number(curVersionArr[i])) {
          if (curVersionArr.length == 1) {
            continue;
          }
          if (i == curVersionArr.length - 1) {
            for (let j = i; j < newVersionArr.length; j++) {
              if (Number(newVersionArr[j]) != 0) {
                return true;
              }
              if (j == newVersionArr.length - 1) {
                return false;
              }
            }
            return true;
          }
        }
      }
    } else {
      for (let i = 0; i < newVersionArr.length; i++) {
        if (Number(newVersionArr[i]) > Number(curVersionArr[i])) {
          return true;
        } else if (Number(newVersionArr[i]) < Number(curVersionArr[i])) {
          return false;
        } else if (Number(newVersionArr[i]) == Number(curVersionArr[i])) {
          if (newVersionArr.length == 1) {
            continue;
          }
          if (i == newVersionArr.length - 1) {
            return false;
          }
        }
      }
    }
  }
  return false;
};

const loginInitStorageAndStore = (rData, vm) => {
  uni.removeStorage({ key: 'pagefrom' });
  vm.$store.commit('delAddress');
  vm.$store.commit('clearMember');
  uni.setStorageSync('memberSecretV2', rData.loginTicket);
  vm.$store.commit('saveMember', rData);
};

const uniLogin = (provider) => {
  return new Promise((resolve, reject) => {
    uni.login({
      provider,
      onlyAuthorize: true,
      success(event) {
        const { code } = event;
        resolve(code);
      },
      fail(err) {
        reject(new Error('登录失败'));
      },
    });
  });
};

const getSystemString = (wgtVersion, timestamp) => {
  console.log(wgtVersion, timestamp);
  const shuffle = (nums) => {
    for (let i = 0; i < nums.length; ++i) {
      const j = Math.floor(Math.random() * (nums.length - i)) + i;
      [nums[i], nums[j]] = [nums[j], nums[i]];
    }
    return nums;
  };

  const getHeadDigit = (min, max) => {
    let str = Math.floor(Math.random() * (max - min + 1) + min).toString();
    let i = max.toString().length - str.length;
    while (i > 0) {
      str = '0' + str;
      i--;
    }
    return str;
  };

  const binaryAnd = (a, b) => {
    let ans = '';
    let add = 0;
    let i = a.length - 1;
    let j = b.length - 1;
    while (i >= 0 || j >= 0) {
      ans = Number(a.charAt(i) == 1 && b.charAt(j) == 1) + ans;
      i--;
      j--;
    }
    return ans;
  };

  const binaryXor = (a, b) => {
    let ans = '';
    let i = a.length - 1;
    let j = b.length - 1;
    while (i >= 0 && j >= 0) {
      ans = Number(a.charAt(i) != b.charAt(j)) + ans;
      i--;
      j--;
    }
    if (i >= 0) ans = a.substring(0, i + 1) + ans;
    else if (j >= 0) ans = b.substring(0, j + 1) + ans;
    return ans;
  };

  const ivArray = [115, 104, 111, 112];
  const dotASCII = 46;
  const iv = Number(shuffle(ivArray).join(''));
  const version = Number(wgtVersion.replace(/\./g, dotASCII));

  const head = getHeadDigit(999, 20000);
  const bodyBinary = binaryAnd(iv.toString(2), timestamp.toString(2));
  const body = parseInt(bodyBinary, 2);
  const tailBinary = binaryXor(bodyBinary, version.toString(2));
  const tail = parseInt(tailBinary, 2);
  // console.log(iv, `${head}-${body}-${tail}`)
  return `${head}${body}${tail}`;
};

module.exports = {
  parseurl,
  isObject,
  debounce,
  throttle,
  dateFormat,
  filterEmpty,
  uniChooseImage,
  uniGetClipboardData,
  uniSetClipboardData,
  uuid,
  getTimeLimit,
  CountDown,
  encryptPassword,
  loadScript,
  compareVersion,
  loginInitStorageAndStore,
  uniLogin,
  getSystemString,
};
